#ifndef GSERVER_H_
#define GSERVER_H_

#define DEBUG

#include <stdint.h>
#include <sys/types.h>
#include <string>
#include <vector>
using std::string;
using std::vector;

//system limits
#define		USR_LEN			128	    //最大用户名长度
#define		PWD_LEN			128     //最大密码长度
#define		PATH_LEN		256		//最大路径长度
#define		FILE_LEN		32		//最长文件名
#define		BUF_SIZE		1024
#define		BLOCK_SIZE		4096	//文件传输的块大小

//data进程中的状态机
#define		DATA_INIT			1
#define		DATA_SYNC			2
#define		DATA_PUSH			3
#define		DATA_PULL			4
#define		SYNC_WAIT_ID		1
#define		SYNC_WAIT_PEER		2
#define		SYNC_WAIT_REAL		3
#define		SYNC_SENDING		4
#define		PUSH_WAIT_ID		1
#define		PUSH_WAIT_PATH		2
#define		PUSH_WAIT_ACK		3
#define		PUSH_SENDING		4
#define		PUSH_RECIVING		5
#define		PULL_WAIT_ID		1
#define		PULL_WAIT_PATH		2
#define		PULL_RECIVING		3
#define		PULL_WAIT_ACK		4
#define		PULL_SENDING		5


//about epoll
#define EPOLL_MAX_FD		5000
#define EPOLL_MAX_EVENTS	10

//端口
#define SRV_DATA_PORT		"1235"
#define SRV_CTL_PORT		"1234"

//通信协议
#define REG					1		//注册
#define LOGIN				2		//登录
#define CREATE_D			3		//新建目录
#define CREATE_F			4		//创建文件
#define DEL_F				5		//删除文件
#define DEL_D				6		//删除目录
#define UP_F				7		//更新文件
#define UP_D				8		//更新目录
#define EXIT				9		//用户退出

//信号量
#define QUEUE_N				0
#define MUTEX				1

//信号量的KEY
#define SEM_KEY				1026

#define SA struct sockaddr

//服务器上的根目录
#define SRV_ROOT "/gsync"


/* ---------------------------------------------------------------*/
/**
 * 简介: 以下4个结构体是与ctl进程相关的  
 */
/* ---------------------------------------------------------------*/
typedef struct id_pair
{
	char		usr[USR_LEN]; //用户名
	char		pwd[PWD_LEN]; //密码
} id_pair_t;

typedef union str
{
	id_pair_t	id;
	char		path[PATH_LEN];
} str_t;

/*控制信息的连接中传的包*/
typedef struct ctl_pkg
{
	uint8_t		type;  
	str_t		str;	
} ctl_pkg_t;

/* 控制连接中每个连接的状态,
 * 记录在events.data.ptr中*/
typedef struct ctl_sock_info
{
	int32_t				fd;
	int32_t				version;
	bool				updated;
	int8_t				state;
	int8_t				reply;
	vector<ctl_pkg_t*>	history;
	char				usr_name[USR_LEN];
} ctl_sock_info_t;


/* 数据连接中每个连接的状态，
 * 记录在events.data.ptr中*/
typedef struct data_sock_info
{
	int32_t				sock_fd;
	int32_t				file_fd;
	size_t				total;			//传输中文件的总字节数
	size_t				tsfd;			//已传输的字节数
	uint32_t			peer_version;	//对方的版本
	uint32_t			real_version;	//服务器版本号
	uint8_t				type;			//INIT SYNC  PUSH  PULL
	int8_t				state;
	char				usr_name[USR_LEN];
	bool				transfering;

} data_sock_info_t;

struct update_head
{
	uint8_t type;
	char usr[USR_LEN];
	char pwd[PWD_LEN];
	char path[PATH_LEN];
};

//函数声明
int init_semvalue(int sem_id, int sem_num);
int sem_wait(int sem_id, int sem_num);
int sem_signal(int sem_id, int sem_num);
ssize_t writen(int fd, const void *vptr, size_t n);
void Writen(int fd, void *ptr, size_t nbytes);
ssize_t readn(int fd, void *vptr, size_t n);
void file_rcv(int det, int src);
void file_copy(int det, int src);
void get_home(string& dir);
void* process_thread(void* gsyncer);
void dir_search(vector<string>& watch_list, string& pre_path);
void usr_exit(ctl_sock_info_t* info);

#endif
